#ifndef __PROTOOL_H__
#define __PROTOOL_H__

#include "struct_typedef.h"


#pragma pack(push)
#pragma pack(1)
typedef struct
{
    uint16_t id;
    float voltage;
    uint16_t pole;
    float kp;
    float ki;
    uint16_t measure_pole;
    float R;
    float H;
    uint16_t can_time_out;
    float max_current;
}read_param_data_pack_t;

#pragma pack(pop)



/* 数据接收缓冲区大小 */
#define PROT_FRAME_LEN_RECV  128

/* 校验数据的长度 */
#define PROT_FRAME_LEN_CHECKSUM    1

/* 数据头结构体 */
typedef __packed struct
{
  uint16_t head;    // 包头
  uint8_t len;     // 包长度
  uint8_t cmd;      // 命令
//  uint8_t sum;      // 校验和
  
}packet_head_t;

#define FRAME_HEADER     0x5A53    // 帧头


/* 指令(下位机 -> 上位机) */
#define SEND_TARGET_CMD      0x01     // 发送上位机通道的目标值
#define PARAM_REPLY_CMD			 0x02
#define FLASH_OK_CMD			 	 0x03
#define VERSION_REPLY_CMD		 0x04
#define READY_UPDATE_CMD		 0x05
/* 指令(上位机 -> 下位机) */
#define CALIBRATION_CMD        0x10     
#define RESET_CMD              0x11   
#define READ_PARAM_CMD         0x12
#define PARAM_SEND_CMD         0x13  
#define CURRENT_SEND_CMD       0x14  //电流发送
#define READ_VERSION_CMD       0x15  //读取系统版本
#define SEND_FIRM_SIZE_CMD     0x16  //发送请求和总大小
/* 空指令 */
#define CMD_NONE             0xFF     // 空指令

/* 索引值宏定义 */
#define HEAD_INDEX_VAL       0x1u     // 包头索引值（2字节）
#define LEN_INDEX_VAL        0x2u     // 包长索引值（1字节）
#define CMD_INDEX_VAL        0x3u     // 命令索引值（1字节）

#define EXCHANGE_H_L_BIT(data)      ((((data) << 24) & 0xFF000000) |\
                                     (((data) <<  8) & 0x00FF0000) |\
                                     (((data) >>  8) & 0x0000FF00) |\
                                     (((data) >> 24) & 0x000000FF))     // 交换高低字节

#define COMPOUND_32BIT(data)        (((*(data-0) << 24) & 0xFF000000) |\
                                     ((*(data-1) << 16) & 0x00FF0000) |\
                                     ((*(data-2) <<  8) & 0x0000FF00) |\
                                     ((*(data-3) <<  0) & 0x000000FF))      // 合成为一个字



struct prot_frame_parser_t
{
    uint8_t *recv_ptr;
    uint16_t r_oft;
    uint16_t w_oft;
    uint16_t frame_len;
    uint16_t found_frame_head;
};






/**
 * @brief   接收数据处理
 * @param   *data:  要计算的数据的数组.
 * @param   data_len: 数据的大小
 * @return  void.
 */
void protocol_data_recv(uint8_t *data, uint16_t data_len);

/**
 * @brief   初始化接收协议
 * @param   void
 * @return  初始化结果.
 */
int32_t protocol_init(void);

/**
 * @brief   接收的数据处理
 * @param   void
 * @return  -1：没有找到一个正确的命令.
 */
int8_t receiving_process(void);

/**
  * @brief 设置上位机的值
  * @param cmd：命令
  * @param ch: 曲线通道
  * @param data：参数指针
  * @param num：参数个数
  * @retval 无
  */
void set_computer_value(uint8_t cmd, void *data, uint8_t num);

uint8_t protocol_frame_parse(uint8_t *data, uint16_t *data_len);


#endif